package com.example.lin.http;

import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.Response;
import com.ecwid.consul.v1.catalog.CatalogServicesRequest;
import com.ecwid.consul.v1.health.HealthServicesRequest;
import com.ecwid.consul.v1.health.model.HealthService;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @className: ConsulServiceStatusPrinter
 * @description: 清除Consul服务实例状态
 * @author: Lin.Gu
 * @date: 2025-08-27  15:20
 */
public class ConsulServiceStatusPrinter {

    public static RestTemplate restTemplate = new RestTemplate();
    private static final String CONSUL_HOST = "10.238.235.88";
    private static final int CONSUL_PORT = 8500;
    private static final String CONSUL_DEREGISTER_URL = "http://" + CONSUL_HOST + ":" + CONSUL_PORT + "/v1/agent/service/deregister/";


    public static void main(String[] args) {
        // 创建ConsulClient实例，默认连接到本地的Consul服务（localhost:8500）
        // 如果你的Consul服务地址或端口不同，请相应修改
        ConsulClient consulClient = new ConsulClient(CONSUL_HOST, CONSUL_PORT);
        // 数据中心参数（默认使用Consul服务器所在的数据中心）
        String dataCenter = null;
        try {

            // 构建CatalogServicesRequest（未过时的方式）
            CatalogServicesRequest catalogRequest = CatalogServicesRequest.newBuilder()
                    .setDatacenter(dataCenter)
                    .setQueryParams(null)
                    .build();

            // 1. 获取所有服务名称
            Response<Map<String, List<String>>> servicesResponse = consulClient.getCatalogServices(catalogRequest);
            Map<String, List<String>> servicesMap = servicesResponse.getValue();

            if (servicesMap == null || servicesMap.isEmpty()) {
                System.out.println("未发现注册的服务");
                return;
            }
            System.out.println("===== Consul服务存活状态 =====");
            // 2. 遍历每个服务
            for (String serviceName : servicesMap.keySet()) {
                System.out.println("\n【服务名称】: " + serviceName);

                // 3. 获取该服务的所有实例（不筛选健康状态）
                HealthServicesRequest allInstancesRequest = HealthServicesRequest.newBuilder()
                        .setPassing(false) // 获取所有实例
                        .build();
                Response<List<HealthService>> allInstancesResponse = consulClient.getHealthServices(serviceName, allInstancesRequest);
                List<HealthService> allInstances = allInstancesResponse.getValue();

                if (allInstances == null || allInstances.isEmpty()) {
                    System.out.println("  无实例注册");
                    continue;
                }

                // 4. 获取该服务的健康实例（仅状态为passing的）
                HealthServicesRequest healthyInstancesRequest = HealthServicesRequest.newBuilder()
                        .setPassing(true) // 仅获取健康实例
                        .build();
                Response<List<HealthService>> healthyInstancesResponse = consulClient.getHealthServices(serviceName, healthyInstancesRequest);
                List<HealthService> healthyInstances = healthyInstancesResponse.getValue();
                int healthyCount = (healthyInstances != null) ? healthyInstances.size() : 0;

                // 5. 打印所有实例信息
                for (HealthService instance : allInstances) {
                    String instanceId = instance.getService().getId();
                    String address = instance.getService().getAddress();
                    String nodeName = instance.getNode().getNode();
                    int port = instance.getService().getPort();

                    // 判断当前实例是否在健康列表中
                    boolean isHealthy = isInstanceInList(instanceId, healthyInstances);

                    System.out.printf("  实例ID: %s | 地址: %s:%d | 状态: %s%n",
                            instanceId,
                            address,
                            port,
                            isHealthy ? "✅ 健康" : "❌ 异常");

                    if(!isHealthy){
                        // 使用RestTemplate发送请求删除实例
                        boolean success = deregisterViaRestTemplate(instanceId);
                        if (success) {
                            System.out.println("成功删除实例：" + instanceId + "（节点：" + nodeName + "）");
                        } else {
                            System.err.println("删除实例失败：" + instanceId);
                        }
                    }
                }

                // 6. 汇总信息
                System.out.printf("  【汇总】: 总实例数=%d, 健康实例数=%d, 异常实例数=%d%n",
                        allInstances.size(),
                        healthyCount,
                        allInstances.size() - healthyCount);
            }

        } catch (Exception e) {
            System.err.println("查询出错: " + e.getMessage());
            e.printStackTrace();
        }
    }

    // 辅助方法：判断实例是否在健康列表中
    private static boolean isInstanceInList(String instanceId, List<HealthService> healthyInstances) {
        if (healthyInstances == null || healthyInstances.isEmpty()) {
            return false;
        }
        for (HealthService healthy : healthyInstances) {
            if (instanceId.equals(healthy.getService().getId())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 使用RestTemplate删除服务实例
     */
    private static boolean deregisterViaRestTemplate(String serviceId) {
        // 1. 构建请求头（指定JSON格式）
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        // 3. 封装请求实体
        HttpEntity<Map<String, String>> requestEntity = new HttpEntity<>(headers);

        // 4. 发送PUT请求并获取响应
        String response = restTemplate.exchange(
                CONSUL_DEREGISTER_URL.concat(serviceId),
                HttpMethod.PUT,
                requestEntity,
                String.class
        ).getBody();

        // 5. Consul成功删除后返回"true"
        return "true".equals(response);
    }


}
